#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pylab
import matplotlib.pyplot           as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib
import numpy
from   numpy        import *
from   PIL          import Image
from   random       import randint
from   matplotlib   import *
from   config       import Config
from   os           import environ
from   os.path      import join
from   pprint       import pprint
from   datos        import vfaces, vfaces_test, cl_train, cl_test
from   clasificador import *
from   recfacial    import *

def muestra_eigencaras( eigencaras, shape ):
    """Construye una imagen que contiene las eigencaras calculadas"""

    em, en = eigencaras.shape
    neig   = en if en < 15 else 15
    rens = int(sqrt(neig))
    cols = en / rens

    pylab.figure()
    pylab.plot()
    pylab.title("Eigencaras")

    for i in range( neig ):
        eigcara = eigencaras[:,i]
        mode = eigcara.reshape(shape)
        pylab.subplot(rens,cols,i+1)
        pylab.gray()
        pylab.imshow(mode)

def muestra_eigval( energia, vpmin, nu ):
    """Grafica los valores propios calculados."""
    plt.figure()
    plt.plot(energia,'-*m', markerfacecolor='pink',markeredgecolor='pink')
    plt.plot(
        vpmin,nu,'-*m',           linewidth=10, markerfacecolor='black',
        markeredgecolor='black', markersize=10)
    plt.axis([-2,12,-0.2,1.2])

def muestra_componentes( comp ):
    """
    Genera una gráfica tridimensional que muestra los tres componentes
    principales calculados
    """
    muestra("Figura 5: Componentes principales")

    fig = pylab.figure ()
    ren, col = comp.shape
    ax = p3.Axes3D (fig)
    x = numpy.array(comp[:,0].transpose(), numpy.int).reshape((ren,))
    y = numpy.array(comp[:,1].transpose(), numpy.int).reshape((ren,))
    z = numpy.array(comp[:,2].transpose(), numpy.int).reshape((ren,))


    print z.shape

    #color= pylab.cm.get_cmap("Greens")
    color = matplotlib.colors.Colormap("Greens", N=256)
    c = matplotlib.cm.get_cmap(color)

    ax.scatter(x, y, z, zdir='z',s=5, cmap=c)
    ax.set_xlabel('X - Primer componente principal')
    ax.set_ylabel('Y - Segundo componente principal')
    ax.set_zlabel('Z - Tercer componente principal')

    fig.add_axes(ax)

    pass


def prueba():
    """Prueba global"""

    conf = Config()
    conf.configura( join(environ["DIRCONF"],'refac.conf') )
    img_shape = 10, 10

    # Función por definir: carga_datos
    # vfaces, vfaces_test = carga_datos()
    k , n  = vfaces.shape
    kt, nt = vfaces_test.shape

    P = acp(vfaces)

    img_media = P.mf.reshape( img_shape )
    muestraimg( img_media, "Imagen media" )

    a, vpmin, nu, EOpt, energia = errorCuadratico( P.d )

    muestra_eigval( energia, vpmin, nu )

    P = acp( vfaces, vpmin - 1 )

    muestra_eigencaras( P.Vp, img_shape )

    muestra_componentes( P.Yfg )

    # Clasificación de las caras de entrenamiento

    for k in range( 1, conf.knn + 1 ):
        P.clases_obt = miKNN( P.Yfg, cl_train, P.Yfg, k )
        P.t_e.append( arrayor ( P.clases_obt, cl_train ) )


    mf    = numpy.matrix( numpy.repeat ( P.mf, nt ) )
    mf    = mf.reshape( kt, nt )
    B     = vfaces_test - mf
    P.Yft = P.Vp.transpose() * B

    for k in range( 1, conf.knn + 1 ):
        P.clases_obt_test = miKNN( P.Yfg, cl_train, P.Yft, k )
        P.t_e_test.append( arrayor ( P.clases_obt_test, cl_test ) )

    #Muestra las imágenes
    pylab.show()


def main():
    """Iniciando la prueba"""

    try:
        dirbd = join( environ["DIRBD"], "bdorl" )
        recfacial.main( dirbd )
    except KeyError as e:
        sys.stderr.write(
            "Variable de entorno no definida: {0}\n".format(str(e))
        )


if __name__ == '__main__':
    prueba()
